using System;
using System.Collections.Generic;
using System.Text;
using Barrage.GUI.Elements;
using System.Xml;
using Barrage.Global;
using SlimDX;
using Barrage.Meshes.Text;
using Barrage.GUI.Meshes;
using Barrage.Textures;
using System.Globalization;

namespace Barrage.GUI.Templates.Standard
{
    struct StandardGUIButtonListOptionAttributes
    {
        const string XML_TEXTURE_ATTRIBUTE = "texture";
        const string XML_HOVER_TEXTURE_ATTRIBUTE = "hoverTexture";
        const string XML_PADDING_ATTRIBUTE = "padding";
        const string XML_BORDER_ATTRIBUTE = "border";
        const string XML_FONTSIZE_ATTRIBUTE = "fontSize";

        public string Texture;
        public string HoverTexture;
        public string CoordBorder;
        public string UVBorder;
        public string BitmapFont;
        public float FontSize;

        const string DEFAULT_TEXTURE = "Standard/buttonListOption.png";
        const string DEFAULT_HOVER_TEXTURE = "Standard/buttonListOptionHover.png";
        const string DEFAULT_COORDBORDER = "45,45,45,45";
        const string DEFAULT_UVBORDER = "0.0439453125,0.3515625,0.0439453125,0.3515625";
        const string DEFAULT_FONT = "Standard";
        const float DEFAULT_FONTSIZE = 24;
        
        public static StandardGUIButtonListOptionAttributes DefaultValues
        {
            get
            {
                return new StandardGUIButtonListOptionAttributes(
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_TEXTURE,
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_HOVER_TEXTURE,
                    DEFAULT_COORDBORDER,
                    DEFAULT_UVBORDER,
                    DEFAULT_FONT,
                    DEFAULT_FONTSIZE
                     );
            }
        }

        public StandardGUIButtonListOptionAttributes(string texture, string hoverTexture, string coordBorder, string UVBorder, string BitmapFont, float FontSize)
        {
            this.Texture = texture;
            this.HoverTexture = hoverTexture;
            this.CoordBorder = coordBorder;
            this.UVBorder = UVBorder;
            this.BitmapFont = BitmapFont;
            this.FontSize = FontSize;
        }
        public StandardGUIButtonListOptionAttributes(XmlNode xn)
        {
            Texture = XmlHelper.GetXMLAttribute(xn, XML_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_TEXTURE);
            HoverTexture = XmlHelper.GetXMLAttribute(xn, XML_HOVER_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_HOVER_TEXTURE);
            CoordBorder = XmlHelper.GetXMLAttribute(xn, XML_PADDING_ATTRIBUTE, DEFAULT_COORDBORDER);
            UVBorder = XmlHelper.GetXMLAttribute(xn, XML_BORDER_ATTRIBUTE, DEFAULT_UVBORDER);
            BitmapFont = DEFAULT_FONT;
            FontSize = XmlHelper.ParseXMLFloatAttribute(xn, XML_FONTSIZE_ATTRIBUTE, DEFAULT_FONTSIZE);
            
        }
    }
    /// <summary>
    /// Standard template implementation of GUIButtonListOption
    /// </summary>
    public class StandardGUIButtonListOption : GUIButtonListOption
    {
        /// <summary>
        /// \internal Size of the item for mouse intersection checking. Can be overrided
        /// </summary>
        protected override Vector2 DefaultSize { get { return new Vector2(450, 80); } }

        const string XML_DEFAULT_ATTRIBUTE = "default";
        StandardGUIButtonListOptionAttributes attributes;
        TextBoxMesh textMesh;
        BorderedRectangle borderedRectangle;
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="layout">Layout that will hold this item</param>
        /// <param name="xn">Xml Node that holds attribute values of this item</param>
        public StandardGUIButtonListOption(GUILayout layout, XmlNode xn)
            : base(layout, GUITemplateTypes.Standard, xn)
        {
            processDefaultValues(xn);

            float[] coordBorder = parseBorders(attributes.CoordBorder);
            float[] uvBorder = parseBorders(attributes.UVBorder);

            borderedRectangle = new BorderedRectangle(TextureManager.Textures[attributes.Texture], Size, coordBorder, uvBorder);
            addMesh(borderedRectangle);

            BitmapFont f = BitmapFontManager.Fonts[attributes.BitmapFont];
            float scale = attributes.FontSize / f.FontInfo.LineHeight;
            textMesh = new TextBoxMesh(f, new TextBoxDrawProperties(TextAlignment.Center, Size, scale, VerticalAlignment.Center, Vector2.Zero));
            textMesh.Text = Text;
            addMesh(textMesh);
            
        }

        void processDefaultValues(XmlNode xn)
        {
            bool loadDefaults = XmlHelper.GetXMLAttribute(xn, XML_DEFAULT_ATTRIBUTE).Equals("true");
            if (loadDefaults)
                attributes = StandardGUIButtonListOptionAttributes.DefaultValues;
            else
                attributes = new StandardGUIButtonListOptionAttributes(xn);

        }

        /// <summary>
        /// \internal Gets / Sets the button text
        /// </summary>
        public override string Text { set { textMesh.Text = value; base.Text = value; } }

        float[] parseBorders(string source)
        {
            float[] border = new float[4] { 0, 0, 0, 0 };
            if (source.Length == 0) return border;
            string[] borderStrings = source.Split(',');
            for (int i = 0; i < Math.Min(4, borderStrings.Length); i++)
            {
                Single.TryParse(borderStrings[i], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out border[i]);
            }
            return border;
        }

        /// <summary>
        /// \internal Updates matrices and item logic
        /// </summary>
        protected override void DoUpdate()
        {
            base.DoUpdate();
            UpdateHover();
        }

        void UpdateHover()
        {
            borderedRectangle.Materials[0].Texture = TextureManager.Textures[Selected ? attributes.HoverTexture: attributes.Texture ];
        }

        /// <summary>
        /// \internal Clear resources
        /// </summary>
        public override void Dispose()
        {
            textMesh = null;
            borderedRectangle = null;
            base.Dispose();
        }
    }
}
